
export interface FanListResponse {
    Data: {
        "LinkedData": {},
        "IsInControl": boolean,
        "SelectedInputTemplateIdString": string,
        "TempatureValNow": number,
        "Id": string,
        "Name": string,
        "DetailDesc": string,
        "ControlMode": string,
        "ControlValue": number,
        "ControlValueMin": number,
        "ControlValueMax": number,
    }[]
}
export interface ProfileInfoResponseItem {
    "CustomName": string,
    "SensorId": string,
    "TemperaureSrcId": string,
    "IsControl": boolean,
    "HideInMain"?: boolean,
    "ControlWays": string,
    "curvePoints":
    {
        "PropsX": number,
        "PropsY": number,
    }[]
}
export interface ProfileInfoResponse {
    Data: ProfileInfoResponseItem[]
}
export interface TempatureListResponseItem {
    "Id": string,
    "Name": string,
    "Desc": string,
    "Val": number,
}
export interface TempatureListResponse {
    Data: TempatureListResponseItem[]
}


export interface VecPoint {
    X: number,
    Y: number,
}


export function clampN(v: number, min: number, max: number) {
    if (v < min) v = min;
    if (v > max) v = max;
    return v;
}
/// x,y(100, 100) ==> Rect
export function ConvertCurvePointToControlPointXY(RBCorner: VecPoint, LTCorner: VecPoint, X: number, Y: number): VecPoint {
    return ConvertCurvePointToControlPoint(RBCorner, LTCorner, { X, Y });
}

export function ConvertCurvePointToControlPoint(RBCorner: VecPoint, LTCorner: VecPoint, input: VecPoint): VecPoint {
    let w = RBCorner.X - LTCorner.X;
    let h = RBCorner.Y - LTCorner.Y;
    let x = LTCorner.X + input.X / 100 * w;
    let y = LTCorner.Y + input.Y / 100 * h;
    return { X: x, Y: y };
}

/// Rect ==> x,y(100, 100)
export function ConvertControlPointToCurvePoint(RBCorner: VecPoint, LTCorner: VecPoint, msPosition: VecPoint): VecPoint {
    let totalWidth = RBCorner.X - LTCorner.X;
    let totalHeight = LTCorner.Y - RBCorner.Y;
    let px = (msPosition.X - LTCorner.X) / totalWidth * 100;
    let py = (msPosition.Y - RBCorner.Y) / totalHeight * 100;
    return { X: px, Y: 100 - py };
}




// 根据 X 计算Y
// 温度曲线
export function CalcYPosWithX(curvePoints: VecPoint[], refancedPointX: number): number | null {
    let copyed = curvePoints.map(item => item);
    copyed.sort((a, b) => (a.X - b.X));

    if (copyed.length < 2) {
        return null;
    }

    if (refancedPointX <= copyed[0].X) {
        return copyed[0].X;
    }
    if (refancedPointX >= copyed[copyed.length - 1].X) {
        return copyed[copyed.length - 1].X;
    }

    for (let i = 0; i < copyed.length - 1; i++) {
        let a = copyed[i];
        let b = copyed[i + 1];
        let inSegment = a.X <= refancedPointX && refancedPointX < b.X;
        if (!inSegment) {
            continue;
        }

        // 计算出投影焦点
        let pop = CalculateIntersection({ X: refancedPointX, Y: 1000 }, { X: refancedPointX, Y: -1000 }, a, b);
        let theY = pop != null ? pop.Y : b.Y;
        let minY = Math.min(a.Y, b.Y);
        let maxY = Math.max(a.Y, b.Y);
        theY = clampN(theY, minY, maxY);
        return theY;
    }

    return null;
}

function VecPointSub(a: VecPoint, b: VecPoint) {
    return { X: a.X - b.X, Y: a.Y - b.Y };
}
function CalculateIntersection(A1: VecPoint, A2: VecPoint, B1: VecPoint, B2: VecPoint): VecPoint | null {
    // 计算线段1和线段2的方向向量
    let D1 = { X: A2.X - A1.X, Y: A2.Y - A1.Y };
    let D2 = { X: B2.X - B1.X, Y: B2.Y - B1.Y };

    // 计算参数t1和t2
    const t1 = CrossProduct(VecPointSub(B1, A1), D2) / CrossProduct(D1, D2);
    const t2 = CrossProduct(VecPointSub(B1, A1), D1) / CrossProduct(D1, D2);

    // 如果t1和t2的取值在[0, 1]之间，表示线段相交
    if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
        // 计算交点坐标
        const intersectionX = A1.X + t1 * D1.X;
        const intersectionY = A1.Y + t1 * D1.Y;
        return { X: intersectionX, Y: intersectionY };
    }

    // 线段不相交
    return null;
}

function CrossProduct(p1: VecPoint, p2: VecPoint): number {
    return p1.X * p2.Y - p1.Y * p2.X;
}